package go_rpc

import (
	"fmt"
	log "github.com/sirupsen/logrus"
	json "gogame/lib"
	"gogame/server/network/tcp"
	"net"
	"runtime/debug"
	"time"
)

type RpcServer struct {
	RpcStruct

	TcpServer *tcp.TcpServer                        // rpcServer 对象
	nodes     map[string]tcp.ConnChannelInterface   // gatewayUrl对应的rpcClient对象
	tags2Conn map[string][]tcp.ConnChannelInterface // rpcClient对象别名对应的链接对象列表
}

// NewRpcServer 实例化RpcClient
func NewRpcServer(listen string) *RpcServer {
	return &RpcServer{
		RpcStruct: RpcStruct{
			Type:    "rpcServer",
			Name:    fmt.Sprintf("rpcServer[%s]", listen),
			Address: listen,
		},
	}
}

// Listen 服务开启
func (r *RpcServer) Listen(network, addr string) (err error) {
	r.TcpServer = &tcp.TcpServer{
		OnConnect: r.onConnect,
	}
	err = r.TcpServer.Listener(network, addr)

	return err
}

// onConnect 链接服务
func (r *RpcServer) onConnect(conn net.Conn) {
	defer func() {
		if over := recover(); over != nil {
			log.Error(over)
			debug.PrintStack()
		}
	}()

	connChannel := tcp.NewConnChannel(conn)
	r.Service = &rpcService{}
	r.rpcHandle = &rpcHandle{
		Name:    r.GetName(),
		Parent:  r,
		Service: r.Service,
		Process: 2,
	}

	// 开始处理
	r.Handle(connChannel)
	// 断开链接
	defer r.OnClose(connChannel)

}

// DoMessage 消息处理
func (r *RpcServer) DoMessage(message *Message) {
	var msgList []interface{}
	err := json.Loads(message.msg, &msgList)
	if err != nil {
		fmt.Println("doMessage err-->", err)
	}
	methodName := msgList[0]
	var args []interface{}
	args = msgList[1].([]interface{})
	apiName := args[0]
	apiArgs := args[1]
	fmt.Printf("%s 收到数据--> method: 【%s】 api: 【%s】 args: %s】 \n", r.GetName(), methodName, apiName, apiArgs)

	fmt.Println("逻辑处理中...")
	time.Sleep(time.Second * 1)
	fmt.Println("逻辑处理完毕...")
	r.rpcHandle.Response(map[string]interface{}{"s": 1})

}

// OnClose rpcClient链接断开
func (r *RpcServer) OnClose(conn tcp.ConnChannelInterface) {
	err := conn.Close()
	if err != nil {
		log.Warning("RpcClient Close error!! -->", err)
	}
}

// Close rpcServer链接断开
func (r *RpcServer) Close() {
	r.TcpServer.Close()
}
